package com.example.webflux.mongo.controller;

import com.example.webflux.mongo.pojo.User;
import com.example.webflux.mongo.repository.UserRepository2;
import com.example.webflux.mongo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/save")
    public Mono<User> save(User user) {
        return this.userService.save(user);
    }

    @GetMapping("/deleteById")
    public Mono<Void> deleteById(String id) {
        return this.userService.deleteById(id);
    }

    @GetMapping("/findById")
    public Mono<User> findById(String id) {
        return this.userService.findById(id);
    }

    @GetMapping("/findAll")
    public Flux<User> findAll() {
        return this.userService.findAll();
    }

    @RequestMapping("/saveAll")
    public Mono<Long> saveAll(@RequestParam(defaultValue = "20000") Integer size) {
        long phone = 15206219182L;
        long start = System.currentTimeMillis();
        List<User> users = new ArrayList<>();
        for (int i=0; i < size; i++) {
            User user = new User();
            user.setPhone(phone + i + "");
            user.setName("webflux" + i);
            user.setEmail(user.getPhone() + "@qq.com");
            user.setStatus(1L);
            user.setCreated(LocalDateTime.now(ZoneId.of("Asia/Shanghai")));
            users.add(user);
        }
        Flux<User> userFlux = userService.saveAll(users);
        System.err.println(System.currentTimeMillis() - start);
        return userFlux.count();
    }

    @Autowired
    UserRepository2 userRepository2;

    @RequestMapping("/saveAll2")
    public int saveAll2(@RequestParam(defaultValue = "20000") Integer size) {
        long phone = 15206219182L;
        long start = System.currentTimeMillis();
        List<User> users = new ArrayList<>();
        for (int i=0; i < size; i++) {
            User user = new User();
            user.setPhone(phone + i + "");
            user.setName("test" + i);
            user.setEmail(user.getPhone() + "@139.com");
            user.setStatus(1L);
            user.setCreated(LocalDateTime.now(ZoneId.of("Asia/Shanghai")));
            users.add(user);
        }
        List<User> list = userRepository2.saveAll(users);
//        Flux<User> userFlux = userService.saveAll(users);
        System.out.println(System.currentTimeMillis() - start);
        return list.size();
    }

    @RequestMapping("/saveAll3")
    public Object saveAll3(@RequestParam(defaultValue = "100") Integer size) {
        long phone = 15206219182L;
        long start = System.currentTimeMillis();
        int line = 1000;
        List<List<User>> list = new ArrayList<>();
        for (int i=0; i < size; i++) {
            List<User> users = new ArrayList<>();
            for (int n=0; n < line; n++){
                User user = new User();
                user.setPhone(phone + n + "");
                user.setName("test" + n);
                user.setEmail(user.getPhone() + "@189.com");
                user.setStatus(1L);
                user.setCreated(LocalDateTime.now());
                users.add(user);
            }
            list.add(users);
        }
        ExecutorService executorService = Executors.newWorkStealingPool();
        int orderSize = list.size();
        for(int i=0; i< orderSize; i++) {
            int n = i;
            executorService.submit(() -> {
                userRepository2.saveAll(list.get(n));
            });
        }
        executorService.shutdown();
        try {
            executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long endTime = (System.currentTimeMillis() - start);
        System.out.println("耗时："+ endTime);
        System.out.println("数据：" + userRepository2.count());

        return endTime;
    }

}
